import { useEffect, useState } from "react";
import { useNavigation } from "@remix-run/react";
import { Button } from "~/components/shared/button";
import { isFormProcessing } from "~/utils/form";
import DynamicSelect from "../dynamic-select/dynamic-select";

import { XIcon } from "../icons/library";
import ImageWithPreview from "../image-with-preview/image-with-preview";

type IsBulk = {
  isBulk: true;
  locationId?: undefined;
};

type IsNotBulk = {
  isBulk: false;
  locationId?: string | null;
};

type BulkProps = IsBulk | IsNotBulk;

/**
 * Shared props for rendering the location selector in bulk or single-item contexts.
 */
type LocationSelectProps = BulkProps & {
  /** Hides the clear (X) button that resets the selection. */
  hideClearButton?: boolean;
  /** Text to show when there is no selected location. */
  placeholder?: string;
  /** Which form field name to bind the selected value to. */
  fieldName?: string;
  /** External value to pre-populate the selector with. */
  defaultValue?: string | null;
  /**
   * When true, the hidden `currentLocationId` input is omitted.
   * Useful when the field is not tied to an existing entity.
   */
  hideCurrentLocationInput?: boolean;
  /** List of location ids that should be hidden from the dropdown (e.g., the current record). */
  excludeIds?: string[];
};

/**
 * LocationSelect wraps DynamicSelect with Shelf-specific behavior such as thumbnail rendering,
 * optional "create new location" entry, and support for excluding certain ids.
 */
export const LocationSelect = ({
  hideClearButton = false,
  placeholder,
  fieldName = "newLocationId",
  defaultValue,
  hideCurrentLocationInput = false,
  excludeIds,
  ...restProps
}: LocationSelectProps) => {
  const navigation = useNavigation();

  const locationIdToUse = !restProps.isBulk ? restProps.locationId : undefined;
  const initialLocationId = defaultValue ?? locationIdToUse;
  const [locationId, setLocationId] = useState(initialLocationId ?? undefined);
  const disabled = isFormProcessing(navigation.state);
  const showCurrentLocationInput =
    !restProps.isBulk && !hideCurrentLocationInput;

  useEffect(() => {
    setLocationId(initialLocationId ?? undefined);
  }, [initialLocationId]);

  return (
    <div className="relative w-full">
      {showCurrentLocationInput && (
        <input
          type="hidden"
          name="currentLocationId"
          value={locationIdToUse ?? undefined}
        />
      )}
      <div className="flex items-center gap-2">
        <DynamicSelect
          disabled={disabled}
          fieldName={fieldName}
          defaultValue={locationId ?? undefined}
          model={{ name: "location", queryKey: "name" }}
          contentLabel="Locations"
          placeholder={placeholder || "Without location"}
          initialDataKey="locations"
          countKey="totalLocations"
          closeOnSelect
          allowClear
          excludeItems={excludeIds}
          onChange={(value) => setLocationId(value)}
          extraContent={
            <Button
              to="/locations/new"
              variant="link"
              icon="plus"
              className="w-full justify-start pt-4"
              target="_blank"
            >
              Create new location
            </Button>
          }
          renderItem={({ name, metadata }) => (
            <div className="flex items-center gap-2">
              {metadata?.thumbnailUrl ? (
                <ImageWithPreview
                  thumbnailUrl={metadata.thumbnailUrl}
                  alt={metadata.name}
                  className="size-6 rounded-[2px]"
                />
              ) : null}
              <div>{name}</div>
            </div>
          )}
        />

        {hideClearButton ? null : (
          <Button
            variant="secondary"
            type="button"
            className="p-3.5"
            onClick={() => setLocationId(undefined)}
            disabled={!locationId}
          >
            <XIcon />
          </Button>
        )}
      </div>
    </div>
  );
};
